# debuggers.py

from __future__ import division

import sys

from PIL import Image, ImageDraw

Max_dimension = 300

class graph(object):
    r'''This graphs any two values.

    ``x`` and ``y`` are a :class:`.param_ref` or :class:`.param_fun`.
    '''

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.reset()

    def reset(self):
        self.points = []        # list of (x, y) pairs

    def point(self, work_to_tool_transform, params):
        self.points.append((self.x.get(params), self.y.get(params)))

    def report(self):
        min_x = min(pt[0] for pt in self.points)
        min_y = min(pt[1] for pt in self.points)
        max_x = max(pt[0] for pt in self.points)
        max_y = max(pt[1] for pt in self.points)
        print >> sys.stderr, "x", min_x, max_x, "y", min_y, max_y

        max_x = max(map(lambda pt: abs(pt[0]), self.points))
        max_y = max(map(lambda pt: abs(pt[1]), self.points))
        scale = Max_dimension / 2.0 / max(max_x, max_y)
        #print "max_x:", max_x, ", max_y:", max_y, ", len(self.points):", len(self.points)
        #print "scale:", scale, ", size:", (int(2 * max_x * scale + 1), int(2 * max_y * scale + 1))
        image = Image.new("1", (int(2 * max_x * scale + 1),
                                int(2 * max_y * scale + 1)))
        drawer = ImageDraw.Draw(image)
        #drawer.line([(0, 0), (100, 100)], fill=255)
        drawer.line([((x + max_x) * scale, (max_y - y) * scale)
                     for x, y in self.points],
                    fill=255)
        self.points = []
        image.show()

class minmax(object):
    r'''This reports the min and max values.

    ``value`` is a :class:`.param_ref` or :class:`.param_fun`.
    '''

    def __init__(self, name, value):
        self.name = name
        self.value = value
        self.reset()

    def reset(self):
        self.min = 1e30
        self.max = -1e30

    def point(self, work_to_tool_transform, params):
        value = self.value.get(params)
        if value < self.min: self.min = value
        if value > self.max: self.max = value

    def report(self):
        print >> sys.stderr, \
          "{name}: min {min}, max {max}" \
            .format(name=self.name, min=self.min, max=self.max)

